<template>
  <div>
    <van-nav-bar
        title="寻路"
        left-arrow
        @click-left="onBack"
        fixed
    />
    <h3>占位</h3>
    <div>
      <label>
        <input type="radio" v-model="viewMode" value="3D"> 3D 模式
      </label>
      <label>
        <input type="radio" v-model="viewMode" value="2D"> 二维
      </label>
    </div>
    <div>
      <div id="map-container"></div>
      <button @click="planRoute" v-if="this.selectedDevice != null">规划路线</button>
      <button @click="removeMarkers">移除标记</button>
    </div>
    <div style="margin-top: 10px">
      <span style="margin-left: -30px">要去的维修设备:</span>
      <select id="dispatch-person" style="width: 200px;height: 25px;margin-left: 35px" v-model="selectedDevice"
              @change="updateDestination">
        <option v-for="item in shebeiName" :value="item.value">{{ item.text }}</option>
      </select>
    </div>
    <div id="panel"
         style="position: relative; margin-top: 10px; width: 100%; height: 200px; background-color: white; padding: 10px; border: 1px solid #ccc;"></div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: "XunluView",
  data() {
    return {
      value: "",
      lat: "",
      lng: "",
      address: "",
      map: null, // 增加 map 属性
      marker: null, // 增加 marker 属性
      driving: null, // 增加 driving 属性
      destination: [0, 0], // 目标位置，可以根据需要修改
      shebeiName: [
        {text: '请选择', value: ''},
        {text: '设备001', value: '[116.397428,39.90923]'},
        {text: '设备002', value: '[113.397428,39.90923]'},
        {text: '设备003', value: '[114.397428,39.90923]'},
      ],
      selectedDevice: '', // 用于存储选中的设备位置
      viewMode: '3D', // 默认渲染模式为3D
      cancelSource: null, // 用于取消网络请求的源
      currentPositionMarker: null, // 当前位置的标记
    }
  },
  watch: {
    viewMode(newVal) {
      this.reinitMap(); // 当渲染模式改变时，重新初始化地图
    }
  },
  methods: {
    /**
     * 更新目的地
     * 当选择要去的维修设备时，更新地图上的标记和中心点位置
     */
    updateDestination() {
      if (this.selectedDevice) {
        // 解析字符串形式的经纬度数组
        this.destination = JSON.parse(this.selectedDevice);
        console.log('新的目的地:', this.destination);
        // 更新地图中心点和标记位置
        if (this.map) {
          this.map.setCenter(this.destination, true, {duration: 1000}); // 添加动画效果
          if (this.marker) {
            this.marker.setPosition(this.destination);
          }
        }
      }
    },

    /**
     * 返回上一页
     */
    onBack() {
      this.$router.go(-1);
    },

    /**
     * 初始化地图
     * 加载地图，并设置初始中心点和缩放级别
     * 创建标记并加载驾车导航插件
     */
    initMap() {
      this.map = new AMap.Map('map-container', {
        pitch: 50, // 地图俯仰角度，有效范围 0 度- 83 度
        viewMode: this.viewMode === '3D' ? '3D' : '2D', // 根据 viewMode 设置地图模式
        rotateEnable: true, // 是否开启地图旋转交互 鼠标右键 + 鼠标画圈移动 或 键盘Ctrl + 鼠标左键画圈移动
        pitchEnable: true, // 是否开启地图倾斜交互 鼠标右键 + 鼠标上下移动或键盘Ctrl + 鼠标左键上下移动
        zoom: 17, // 初始化地图层级
        rotation: -15, // 初始地图顺时针旋转的角度
        zooms: [2, 20], // 地图显示的缩放级别范围
        center: [116.333926, 39.997245] // 初始地图中心经纬度
      });

      // 加载驾车导航插件
      AMap.plugin(['AMap.Driving'], () => {
        this.driving = new AMap.Driving({
          map: this.map,
          panel: 'panel', // 设置导航面板
          autoFitView: true
        });
      });

      // 地图初始化完成后调用 getRegeo
      if (this.lng && this.lat) {
        this.getRegeo(this.lng, this.lat);
      }

      // 创建一个标记
      this.marker = new AMap.Marker({
        icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
        position: [116.397428, 39.90923]
      });

      // 将标记添加到地图上
      this.map.add(this.marker);
    },

    /**
     * 重新初始化地图
     * 当渲染模式改变时，重新初始化地图
     */
    reinitMap() {
      if (this.map) {
        this.map.destroy(); // 销毁旧的地图实例
      }
      this.initMap(); // 初始化新的地图实例
    },

    /**
     * 根据经纬度获取地址信息
     * @param {number} lng 经度
     * @param {number} lat 纬度
     */
    getRegeo(lng, lat) {
      let geocoder;
      // 加载高德地图地理编码插件
      AMap.plugin('AMap.Geocoder', () => {
        // 实例化地理编码服务
        geocoder = new AMap.Geocoder();
        // 根据经纬度获取地址信息
        geocoder.getAddress([lng, lat], (status, result) => {
          // 打印结果用于调试
          console.log(result);
          console.log(status);
          // 如果请求成功且结果正常，则更新地址信息
          if (status === 'complete' && result.info === 'OK') {
            this.address = result.regeocode.formattedAddress;
            console.log(this.address);
            // 设置地图中心点
            if (this.map) {
              this.map.setCenter([lng, lat], true, {duration: 1000}); // 添加动画效果
              // 更新标记位置
              if (this.marker) {
                this.marker.setPosition([lng, lat]);
              }
            }
          } else {
            // 打印错误信息用于调试
            console.log('逆地理编码失败', result);
          }
        });
      });
    },

    /**
     * 获取当前位置成功时的回调函数
     * @param {Position} position 当前位置信息
     */
    successCallback(position) {
      // 获取当前的经纬度
      this.lat = position.coords.latitude;
      this.lng = position.coords.longitude;
      // 保留小数点后6位
      let lng = parseFloat(this.lng.toFixed(6));
      let lat = parseFloat(this.lat.toFixed(6));
      console.log("lng: " + lng + ", lat: " + lat);
      this.getRegeo(lng, lat);
      // 创建或更新当前位置的标记
      this.createOrUpdateCurrentPositionMarker([lng, lat]);
    },

    /**
     * 获取当前位置失败时的回调函数
     * @param {PositionError} error 错误信息
     */
    errorCallback(error) {
      switch (error.code) {
        case error.PERMISSION_DENIED:
          console.log("用户拒绝了地理定位请求。");
          break;
        case error.POSITION_UNAVAILABLE:
          console.log("位置信息不可用。");
          break;
        case error.TIMEOUT:
          console.log("获取用户位置的请求超时。");
          break;
        case error.UNKNOWN_ERROR:
          console.log("发生未知错误。");
          break;
      }
      // 使用IP地址定位
      this.getLocationByIP();
    },

    /**
     * 使用IP地址定位
     */
    getLocationByIP() {
      axios.get('https://ipinfo.io/json')
        .then(response => {
          const loc = response.data.loc.split(',');
          this.lat = parseFloat(loc[0]);
          this.lng = parseFloat(loc[1]);
          console.log("IP定位: lng: " + this.lng + ", lat: " + this.lat);
          this.getRegeo(this.lng, this.lat);
          // 创建或更新当前位置的标记
          this.createOrUpdateCurrentPositionMarker([this.lng, this.lat]);
        })
        .catch(error => {
          console.error('IP定位失败', error);
        });
    },

    /**
     * 规划路线
     * 使用驾车导航插件规划从当前位置到目的地的路线
     */
    planRoute() {
      if (this.driving) {
        this.driving.search([this.lng, this.lat], this.destination, (status, result) => {
          if (status === 'complete') {
            console.log('导航成功', result);
          } else {
            console.log('导航失败', result);
          }
        });
      }
    },

    /**
     * 创建或更新当前位置的标记
     * @param {Array} position [经度, 纬度]
     */
    createOrUpdateCurrentPositionMarker(position) {
      if (!this.currentPositionMarker) {
        // 创建一个新的标记
        this.currentPositionMarker = new AMap.Marker({
          icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png", // 使用红色圆点图标表示当前位置
          position: position,
          title: '当前位置'
        });
        // 将标记添加到地图上
        this.map.add(this.currentPositionMarker);
      } else {
        // 更新现有标记的位置
        this.currentPositionMarker.setPosition(position);
      }
    },

    /**
     * 移除所有标记
     */
    removeMarkers() {
      if (this.marker) {
        this.marker.remove();
        this.marker = null;
      }
      if (this.currentPositionMarker) {
        this.currentPositionMarker.remove();
        this.currentPositionMarker = null;
      }
    }
  },
  mounted() {
    this.initMap();
  },
  created() {
    // 检查是否支持定位
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(this.successCallback, this.errorCallback);
    } else {
      console.log("Geolocation is not supported by this browser.");
      // 使用IP地址定位
      this.getLocationByIP();
    }
  },
  beforeDestroy() {
    if (this.map) {
      this.map.destroy();
      this.map = null;
      this.marker = null;
      this.driving = null;
    }
    if (this.cancelSource) {
      this.cancelSource.cancel('由于导航问题，操作已取消。');
    }
  }
}
</script>

<style scoped>
#map-container {
  width: 100%;
  height: 500px; /* 根据需要调整高度 */
}
</style>
